package com.spring.study.bean.definition;

import com.spring.study.domain.User;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.ListableBeanFactory;
import org.springframework.beans.factory.ObjectFactory;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class TypeSafetyDependencyLookupDemo {

    public static void main(String[] args) {
        //创建BeanFactory容器
        AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
        //将当前类作为配置类
        applicationContext.register(TypeSafetyDependencyLookupDemo.class);
        //启动应用上下文
        applicationContext.refresh();
        //演示BeanFactory.getBean安全性
        displayBeanFactoryGetBean(applicationContext);
        //演示ObjectFactory.getObject安全性
        displayObjectFactoryGetObject(applicationContext);
        //演示ObjectProvider.getIfAvailable();
        displayObjectProviderGetIfAvilable(applicationContext);

        //演示ListableBeanFactory.getBeanOfType
        displayListableBeanFactoryGetBeanOfType(applicationContext);
        //演示ObjectProvider的stream
        displayObjectProviderStreamOps(applicationContext);

        //关闭一能用上下文
        applicationContext.close();
    }

    private static void displayObjectProviderStreamOps(AnnotationConfigApplicationContext applicationContext) {
        ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
        printBeanException("displayObjectProviderStreamOps",() -> userObjectProvider.forEach(System.out::println));
    }

    private static void displayListableBeanFactoryGetBeanOfType(ListableBeanFactory beanFactory) {
        printBeanException("displayListableBeanFactoryGetBeanOfType",() -> beanFactory.getBeansOfType(User.class));
    }

    private static void displayObjectProviderGetIfAvilable(AnnotationConfigApplicationContext applicationContext) {
        ObjectProvider<User> userObjectProvider = applicationContext.getBeanProvider(User.class);
        printBeanException("displayObjectProviderGetIfAvilable",() -> userObjectProvider.getIfAvailable());
    }

    private static void displayObjectFactoryGetObject(AnnotationConfigApplicationContext applicationContext) {
        //ObjectProvider is ObjectFactory
        ObjectFactory<User> userObjectFactory = applicationContext.getBeanProvider(User.class);
        printBeanException("displayObjectFactoryGetObject",() -> userObjectFactory.getObject());
    }

    private static void displayBeanFactoryGetBean(BeanFactory beanFactory) {
        printBeanException("displayBeanFactoryGetBean",() -> beanFactory.getBean(User.class));
    }

    private static void printBeanException(String source,Runnable runnable) {
        System.err.println("=======================");
        System.err.println("source form: "+source);
        try {
            runnable.run();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }















}
